package com.lsj.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lsj.config.redis.RedisKey;
import com.lsj.core.exception.CustomerException;
import com.lsj.core.page.QueryPage;
import com.lsj.core.page.ResultPage;
import com.lsj.core.response.ResponseType;
import com.lsj.core.util.QueryHelperUtil;
import com.lsj.dto.sys.DictAddDto;
import com.lsj.dto.sys.DictDeleteDto;
import com.lsj.dto.sys.DictDto;
import com.lsj.dto.sys.DictUpdateDto;
import com.lsj.mapper.SysDictMapper;
import com.lsj.mapper.entity.SysDict;
import com.lsj.service.DictService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Author:lin.sj
 * @Data:2021/8/2 21:34
 * @Desc:
 */
@Service
@CacheConfig(cacheNames = RedisKey.DICT_KEY)
public class DictServiceImpl implements DictService {

    @Autowired
    SysDictMapper sysDictMapper;

    /**
     * @Author: lin.sj
     * @Date: 2021/8/18 20:41
     * @Desc: 新增字典信息
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(key = "#dto.fieldName")
    public DictDto addDict(DictAddDto dto) {
        //检查是否有相同name-value的数据
        List<SysDict> sysDicts = getExistsDict(dto.getFieldName(), dto.getFieldValue());
        if(sysDicts.size() >0){
            throw new CustomerException(ResponseType.error,"存在相同字段名称和字段值的数据，不允许保存！");
        }
        SysDict sysDict = Convert.convert(SysDict.class, dto);
        sysDict.setEnabled(true);
        sysDictMapper.insert(sysDict);
        return Convert.convert(DictDto.class,sysDict);
    }

    /**
     * @Author: lin.sj
     * @Date: 2021/8/18 20:41
     * @Desc: 删除字典信息
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(key = "#dto.fieldName")
    public void deleteDict(DictDeleteDto dto) {
        sysDictMapper.deleteById(dto.getId());
    }
    /**
     * @Author: lin.sj
     * @Date: 2021/8/18 20:41
     * @Desc: 获取字典信息
     **/
    @Override
    public DictDto getDictById(Long dictId) {
        SysDict sysDict = sysDictMapper.selectById(dictId);
        return Convert.convert(DictDto.class,sysDict);
    }

    /**
     * @Author: lin.sj
     * @Date: 2021/8/18 20:41
     * @Desc: 更新字典信息
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(key = "#dto.fieldName")
    public void updateRole(DictUpdateDto dto) {
        List<SysDict> sysDicts = getExistsDict(dto.getFieldName(), dto.getFieldValue());
        SysDict dict = null;
        for(SysDict d:sysDicts){
            if(d.getId().equals(dto.getId())){
                dict = d;
                continue;
            }else if(d.getFieldValue().equals(dto.getFieldValue()) && d.getFieldName().equals(dto.getFieldName())){
                throw new CustomerException(ResponseType.error,"存在相同字段名称和字段值的数据，不允许保存！");
            }
        }
        BeanUtils.copyProperties(dto,dict);
        sysDictMapper.updateById(dict);
    }

    /**
     * @Author: lin.sj
     * @Date: 2021/8/18 20:42
     * @Desc: 获取字典列表
     **/
    @Override
    public ResultPage<DictDto> listDict(QueryPage<DictDto> queryPage) {
        QueryWrapper<SysDict> w = QueryHelperUtil.getSimpleWhere(SysDict.class, queryPage.getData());
        Page page = sysDictMapper.selectPage(queryPage.getMpPage(), w);
        return ResultPage.getResult(page,DictDto.class);
    }

    /**
     * @Author: lin.sj
     * @Date: 2021/8/18 20:42
     * @Desc: 根据字段名称和键值查询是否存在对应的字典信息(公用方法)
     **/
    private List<SysDict> getExistsDict(String fieldName,String fieldValue){
        LambdaQueryWrapper<SysDict> w = QueryHelperUtil.getLambdaWrapper(SysDict.class);
        w.eq(SysDict::getFieldName,fieldName)
                .eq(SysDict::getFieldValue,fieldValue);
        List<SysDict> sysDicts = sysDictMapper.selectList(w);
        return sysDicts;
    }
}
